﻿<!DOCTYPE HTML>
<html lang="zh">
<head>
<title>OnExit - 语法 &amp; 使用 | AutoHotkey v2</title>
<meta name="description" content="The OnExit function causes the specified function to be called automatically when the script exits." />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="../static/theme.css" rel="stylesheet" type="text/css" />
<script src="../static/content.js" type="text/javascript"></script>
<script type="text/javascript">$(function(){0<=window.navigator.userAgent.toLowerCase().indexOf("ucbrowser")&&CaoNiMaDeUc()})</script>
</head>
<body>

<h1>OnExit</h1>

<p>当脚本退出时, 会自动调用指定的函数.</p>

<pre class="Syntax"><span class="func">OnExit</span> Function <span class="optional">, AddRemove</span></pre>
<h2 id="Parameters">参数</h2>
<dl>

  <dt>Function</dt>
  <dd>
    <p>类型: <a href="../objects/Functor.htm">函数对象</a></p>
    <p>脚本退出时调用的函数对象. 函数的参数和返回值<a href="#Function">如下</a>所示.</p>
  </dd>
  
  <dt>AddRemove</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#numbers">整数</a></p>
    <p>如果为空或省略, 则默认为 1(在所有之前注册的函数之后调用该函数). 否则, 请指定以下数字之一:</p>
    <ul>
      <li>1 = 在所有之前注册的函数之后调用该函数.</li>
      <li>-1 = 在所有之前注册的函数之前调用该函数.</li>
      <li>0 = 不调用该函数.</li>
    </ul>
  </dd>

</dl>

<h2 id="Function">Function</h2>
<p>函数应该接受两个参数:</p>
<pre class="Syntax"><i>FunctionName</i>(ExitReason, ExitCode)</pre>
<dl>
  <dt>ExitReason</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
    <p>下列单词之一:</p>
    <table class="info" id="ExitReason">
      <tr>
    <th>单词</th>
    <th>意义</th>
  </tr>
  <tr id="logoff">
    <td>Logoff</td>
    <td>用户正在注销.</td>
  </tr>
  <tr>
    <td>Shutdown</td>
    <td>正在关闭或重启系统, 例如使用 <a href="Shutdown.htm">Shutdown</a> 函数.</td>
  </tr>
  <tr id="close">
    <td>Close</td>
    <td>
     <p>脚本发送 WM_CLOSE 或 WM_QUIT 消息, 出现致命错误, 或者正在被其他方式关闭. 尽管这些情况都是很少见的, 然而 WM_CLOSE 可能是由于在脚本主窗口使用 <a href="WinClose.htm">WinClose</a> 而引起的. 要关闭(隐藏) 窗口而不终止脚本, 请使用 <a href="WinHide.htm">WinHide</a>.</p>
      <p>如果脚本因严重错误或其<a href="../Program.htm#main-window">主窗口</a>被被销毁而退出, 它将在 OnExit 线程完成后无条件终止.</p>
      <p>如果主窗口正在被销毁, 它可能仍然存在, 但不能显示. 这个条件可以通过使用 <a href="OnMessage.htm">OnMessage</a> 监听 WM_DESTROY 消息来检测.</p>
    </td>
  </tr>
  <tr>
    <td>Error</td>
    <td>在不是<a href="../Scripts.htm#persistent">持续运行的</a>脚本中发生了运行时错误. 运行时错误的一个例子是 <a href="Run.htm">Run/RunWait</a> 无法启动指定的程序或打开指定的文档.</td>
  </tr>
  <tr>
    <td>Menu</td>
    <td>用户在主窗口的菜单或标准托盘菜单中选择了 Exit.</td>
  </tr>
  <tr>
    <td>Exit</td>
    <td>使用了 <a href="Exit.htm">Exit</a> 或 <a href="ExitApp.htm">ExitApp</a> 函数(包括<a href="../objects/Menu.htm">自定义菜单项</a>).</td>
  </tr>
  <tr>
    <td>Reload</td>
    <td>正通过 <a href="Reload.htm">Reload</a> 函数或菜单项重载脚本.</td>
  </tr>
  <tr>
    <td>Single</td>
    <td>由于 <a href="_SingleInstance.htm">#SingleInstance</a> 的原因, 脚本正被它自身的新实例代替.</td>
  </tr>
</table>
  </dd>
  <dt>ExitCode</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#numbers">整数</a></p>
    <p>一个介于 -2147483648 和 2147483647 之间的整数, 在脚本退出时返回给它的调用者. 任何生成脚本的程序都可以访问此代码, 例如另一个脚本(通过 RunWait) 或批处理(.bat) 文件. 零通常被用来表示成功.</p>
  </dd>
</dl>

<h3 id="Return_Value">返回值</h3>
<p>函数可以返回一个非零的整数, 以防止脚本退出(除了一些<a href="#close">罕见的例外情况</a>) 和后续函数被调用. 否则, 在所有注册的函数被调用后, 脚本退出.</p>

<h2 id="Remarks">备注</h2>
<p>可以注册任意多个 OnExit 函数. OnExit 函数通常不应该调用 ExitApp; 如果调用了, 脚本将会立即退出.</p>
<p>当脚本以任何方式退出时, 将调用 OnExit 函数(除非被类似 "结束任务" 的方式强行终止). 每当 <a href="_SingleInstance.htm">#SingleInstance</a> 和 <a href="Reload.htm">Reload</a> 请求前一个实例终止时, 也会调用它.</p>
<p>脚本可以通过 <code>OnMessage(0x11, On_WM_QUERYENDSESSION)</code>(有关工作脚本, 请参阅 <a href="OnMessage.htm#ExShutdown">OnMessage 示例 #2</a>) 来检测和是否选择中止系统关闭或注销.</p>
<p>OnExit <a href="../misc/Threads.htm">线程</a>不遵守 <a href="_MaxThreads.htm">#MaxThreads</a>(它总是在需要的时候启动). 此外, 当它运行时, 它不会被任何<a href="../misc/Threads.htm">线程</a>中断, 包括<a href="../Hotkeys.htm">热键</a>, <a href="../objects/Menu.htm">自定义菜单项</a>和<a href="SetTimer.htm">计时器子程序</a>. 不过, 它会在这些情况下被中断(终止)(且脚本也同时被终止了), 用户从托盘菜单或主菜单栏中选择 Exit, 或由于 <a href="Reload.htm">Reload</a> 或 <a href="_SingleInstance.htm">#SingleInstance</a> 而要求脚本终止. 由于这些原因, OnExit 函数应该被设计为尽快结束, 除非用户知道该怎么做.</p>
<p>如果 OnExit <a href="../misc/Threads.htm">线程</a>遇到失败条件, 比如运行错误时, 脚本将会终止.</p>
<p>如果 OnExit <a href="../misc/Threads.htm">线程</a>是由 <a href="Exit.htm">Exit</a> 或 <a href="ExitApp.htm">ExitApp</a> 函数启动并指定了退出码, 则将使用该退出码, 除非 OnExit 函数返回 true(阻止退出) 或调用了 ExitApp.</p>
<p>每当进行一个退出尝试时, 每个 OnExit 函数都使用 <a href="SendMode.htm">SendMode</a> 等设置的默认值重新启动. 这些默认值可以在<a href="../Scripts.htm#auto">自动执行段</a>中更改.</p>

<h2 id="Related">相关</h2>
<p><a href="OnError.htm">OnError</a>, <a href="OnMessage.htm">OnMessage</a>, <a href="CallbackCreate.htm">CallbackCreate</a>, <a href="OnClipboardChange.htm">OnClipboardChange</a>, <a href="ExitApp.htm">ExitApp</a>, <a href="Shutdown.htm">Shutdown</a>, <a href="Persistent.htm">Persistent</a>, <a href="../misc/Threads.htm">线程</a>, <a href="Return.htm">Return</a></p>

<h2 id="Examples">示例</h2>
<div class="ex" id="ExAdvanced">
<p><a class="ex_number" href="#ExBasic"></a> 在退出脚本之前询问用户. 要测试它们, 右击托盘图标然后单击 Exit(退出).</p>
<pre class="NoIndent">Persistent  <em>; 阻止脚本自动退出.</em>
OnExit ExitFunc

ExitFunc(ExitReason, ExitCode)
{
    if ExitReason != "Logoff" and ExitReason != "Shutdown"
    {
        Result := MsgBox("Are you sure you want to exit?",, 4)
        if Result = "No"
            return 1  <em>; OnExit 函数必须返回非零值来阻止退出.</em>
    }
    <em>; 不要调用 ExitApp -- 这会阻止其他 OnExit 函数的调用.</em>
}</pre>
</div>

<div class="ex" id="ExFnObj">
<p><a class="ex_number" href="#ExFnObj"></a> 注册一个在退出时调用的对象.</p>
<pre><a href="Persistent.htm">Persistent</a>  <em>; 阻止脚本自动退出.</em>
OnExit(<a href="ObjBindMethod.htm">ObjBindMethod</a>(MyObject, "Exiting"))

class MyObject
{
    Exiting()
    {
        MsgBox "MyObject is cleaning up prior to exiting..."
        <em>/*
        this.SayGoodbye()
        this.CloseNetworkConnections()
        */</em>
    }
}</pre>
</div>

</body>
</html>